package com.rongmai.web.bo;

import com.alibaba.fastjson.JSON;
import com.aliyun.dypnsapi20170525.models.GetMobileResponse;
import com.aliyun.dypnsapi20170525.models.GetMobileResponseBody;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.rongmai.db.exception.BzException;
import com.rongmai.db.mapper.MsgSmsMapper;
import com.rongmai.db.model.MsgSms;
import com.rongmai.db.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.aliyun.tea.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Slf4j
@Service
public class MessageBo {

    @Value("${ALIBABA_CLOUD_ACCESS_KEY_ID}")
    private String accessKeyId;
    @Value("${ALIBABA_CLOUD_ACCESS_KEY_SECRET}")
    private String accessKeySecret;

    @Value("${ALIBABA_CLOUD_SMSTEMPLATECODE:SMS_463595793}")
    private String smsTemplateCode;

    private final static String signName = "北京圆形圈子科技有限公司";

    @Resource
    private MsgSmsMapper msgSmsMapper;



    public String getMobile(String token) throws Exception {
        // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
        com.aliyun.dypnsapi20170525.Client client = this.createClient(accessKeyId, accessKeySecret);
        com.aliyun.dypnsapi20170525.models.GetMobileRequest getMobileRequest = new com.aliyun.dypnsapi20170525.models.GetMobileRequest();
        getMobileRequest.setAccessToken(token);
        getMobileRequest.setOutId(System.currentTimeMillis() + "");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            log.info("获取手机号入参:{}", JSON.toJSONString(getMobileRequest));
            GetMobileResponse mobileWithOptions = client.getMobileWithOptions(getMobileRequest, runtime);
            log.info("获取手机号出参:{}", JSON.toJSONString(mobileWithOptions));
            GetMobileResponseBody responseBody = mobileWithOptions.getBody();
            String code = responseBody.getCode();
            if ("OK".equals(code)) {
                GetMobileResponseBody.GetMobileResponseBodyGetMobileResultDTO getMobileResultDTO = responseBody.getMobileResultDTO;
                if (!StringUtils.isEmpty(getMobileResultDTO.getMobile())) {
                    return getMobileResultDTO.getMobile();
                } else {
                    throw new BzException("获取手机号为空");
                }
            } else {
                throw new BzException(responseBody.getMessage());
            }
        }catch (TeaException e) {
            log.error("获取手机号异常", e);
            throw new BzException(e.message);
        }
    }

    public void sentSms(String mobile) throws Exception {
        try {
            com.aliyun.dysmsapi20170525.Client client = createSmsClient(accessKeyId, accessKeySecret);
            com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest();
            sendSmsRequest.setPhoneNumbers(mobile);
            sendSmsRequest.setSignName(signName);
            sendSmsRequest.setTemplateCode(smsTemplateCode);
            sendSmsRequest.setOutId(System.currentTimeMillis() + "");
            Map<String, String> param = new HashMap<>();
            String smsCode = getSmsCode();
            param.put("code", smsCode);
            sendSmsRequest.setTemplateParam(JSON.toJSONString(param));
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            // 复制代码运行请自行打印 API 的返回值
            log.info("发送验证码入参:{}", JSON.toJSONString(sendSmsRequest));
            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
            log.info("发送验证码出参:{}", JSON.toJSONString(sendSmsResponse));
            if (!"OK".equals(sendSmsResponse.getBody().getCode())) {
                throw new BzException(sendSmsResponse.getBody().getMessage());
            }
            createMsgSms(mobile, smsCode);
            log.info("msgSms插入成功");
        } catch (TeaException error) {
            log.error("验证码发送异常", error);
            // 如有需要，请打印 error
            throw new BzException(error.message);
        }
    }

    public static com.aliyun.dypnsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // Endpoint 请参考 https://api.aliyun.com/product/Dypnsapi
        config.endpoint = "dypnsapi.aliyuncs.com";
        return new com.aliyun.dypnsapi20170525.Client(config);
    }


    public com.aliyun.dysmsapi20170525.Client createSmsClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    private String getSmsCode() {
        Random rand = new Random();
        int randomNum = rand.nextInt(9000) + 1000;  //生成6位数的随机数
        return String.valueOf(randomNum);
    }

    private void createMsgSms(String phone, String sms) {
        MsgSms msgSms = new MsgSms();
        msgSms.setSms(sms);
        msgSms.setPhone(phone);
        msgSms.setCreateTime(new Date());
        msgSmsMapper.insert(msgSms);
    }

    public void checkSms(String mobile, String smsCode) {

        MsgSms msgSms = msgSmsMapper.selectLatestSms(mobile);
        if (msgSms == null) {
            throw new BzException("验证码不存在");
        }
        if (!smsCode.equals(msgSms.getSms())) {
            throw new BzException("验证码不正确");
        }
        long minutes = DateUtils.diffMinutes(msgSms.getCreateTime());
        if (minutes > 5) {
            throw new BzException("验证码失效");
        }
    }
}
